/**
 * @project: parallel-task
 * @package: com.ngplat.paralleltask.task
 * @filename: TaskContext.java
 *
 * Copyright (c) 2018 eSunny Info. Tech Ltd. All rights reserved.
 * 
 */
package com.ngplat.paralleltask.task;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ngplat.paralleltask.exception.TaskExecutionException;

/**
 * @typename: TaskContext
 * @brief: 任务执行的上下文
 * @author: KI ZCQ
 * @date: 2018年5月28日 下午7:06:15
 * @version: 1.0.0
 * @since
 * 
 */
public class TaskContext implements TaskExecutionResult {

	private static final Logger logger = LoggerFactory.getLogger(TaskContext.class);

	/**
	 * 执行环境上下文属性(参数, Key, Value自己定义)
	 */
	private Map<String, Object> attribute = new ConcurrentHashMap<String, Object>();

	/**
	 * 一组执行结果仓库(Key, Value自己定义)
	 */
	private Map<String, Object> result = new ConcurrentHashMap<String, Object>();

	/**
	 * 一组结果Exception仓库
	 */
	private Map<String, Exception> exception = new ConcurrentHashMap<String, Exception>();

	/**
	 * private constructor.
	 */
	private TaskContext() {
		// 该接口对外封闭
	}

	/**
	 * @Description: 工厂方法，方便后续组装扩展
	 * @return TaskContext实例
	 */
	public static TaskContext newContext() {
		return new TaskContext();
	}

	/**
	 * @see com.ngplat.paralleltask.common.Cleanable#cleanResource()
	 */
	@Override
	public void cleanResource() {
		if (result != null) {
			result.clear();
			result = null;
			exception.clear();
			exception = null;
		}
	}

	/**
	 * @see com.ngplat.paralleltask.task.TaskExecutionResult#putResult(java.lang.String,
	 *      java.lang.Object)
	 */
	@Override
	public <E> void putResult(String key, E value) {
		if (value != null) {
			result.put(key, value);
		}
	}

	/**
	 * @see com.ngplat.paralleltask.task.TaskExecutionResult#getResult(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <E> E getResult(String taskName) {
		Exception ex = exception.get(taskName);
		if (ex != null) {
			logger.error("Execute fail:", ex);
			if (ex instanceof RuntimeException) {
				throw (RuntimeException) ex;
			} else {
				throw new TaskExecutionException(ex);
			}
		}
		return (E) result.get(taskName);
	}

	/**
	 * @see com.ngplat.paralleltask.task.TaskExecutionResult#getResult()
	 */
	@Override
	public Map<String, Object> getResult() {
		return result;
	}

	@SuppressWarnings("unchecked")
	public <T> T getAttribute(String key) {
		return (T) attribute.get(key);
	}

	/**
	 * @Description: 存放参数信息
	 * @param key
	 * @param value
	 * @return
	 */
	public <T> TaskContext putAttribute(String key, T value) {
		attribute.put(key, value);
		return this;
	}
	
	/**
	 * @Description: 存放异常信息
	 * @param key 任务Id
	 * @param e 异常信息
	 */
	public void putException(String key, Exception e) {
		exception.put(key, e);
	}
	
	/**
	 * @Description: 是否有异常信息 
	 * @param key 	任务Id
	 * @return 
	 */
	public Exception getException(String key) {
		// 无异常
		if(exception == null || exception.size() == 0) {
			return null;
		}
		// 获取相应key的异常信息
		return exception.get(key);
	}

}
